import datetime
from rest_framework import serializers
from .models import Blog, BlogPV, DailyPV, Category
from user.serializers import AuthorSerializer


class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ('id', 'name')


class BlogPVSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPV
        fields = ('click_num', 'valid_click_num')


class DailyPVSerializer(serializers.ModelSerializer):
    date = serializers.DateField(format="%Y-%m-%d")

    class Meta:
        model = DailyPV
        fields = ('date', 'click_num', 'valid_click_num')

    def to_representation(self, instance):
        ret = super().to_representation(instance)
        ret['span'] = (datetime.date.today() - instance.date).days  # 距离今天的天数
        return ret


class BlogSerializer(serializers.ModelSerializer):
    page_view = BlogPVSerializer(read_only=True, source="pv")
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M")

    class Meta:
        model = Blog
        fields = ('id', 'author', 'category', 'title', 'content',
                  'cover_picture', 'create_time', 'page_view')
        read_only_fields = ('author',)

    def to_representation(self, instance):
        """
        当是read的方法时，展示完整的user信息
        当是write的方法时，只需要传入author的id
        """
        self.fields['author'] = AuthorSerializer(read_only=True)
        self.fields['category'] = CategorySerializer(read_only=True)
        res = super().to_representation(instance)
        previous_blog = Blog.objects.filter(create_time__lt=instance.create_time).first()
        res['previous'] = {"id": previous_blog.pk, "title": previous_blog.title} if previous_blog else None
        next_blog = Blog.objects.filter(create_time__gt=instance.create_time).last()
        res['next'] = {"id": next_blog.pk, "title": next_blog.title} if next_blog else None
        return res

    def to_internal_value(self, data):
        category = data.get('category')
        try:
            category = int(category)
        except ValueError:
            # category不是id
            try:
                category = Category.objects.get(name=category).pk
            except Category.DoesNotExist:
                raise serializers.ValidationError(f'博客类别: {category} 不存在')
            except Exception:
                raise serializers.ValidationError({'category': f'category 只允许是名称或id'})
        finally:
            data['category'] = category
            return super().to_internal_value(data)


class BlogListSerialize(serializers.ModelSerializer):
    """
    仅用于展示博客列表
    """
    page_view = BlogPVSerializer(read_only=True, source="pv")
    create_time = serializers.DateTimeField(format="%Y-%m-%d", read_only=True)  # 不显示分秒
    author = AuthorSerializer(read_only=True)
    category = CategorySerializer(read_only=True)

    class Meta:
        model = Blog
        fields = ('id', 'author', 'category', 'title', 'description',
                  'cover_picture', 'create_time', 'page_view')

    def to_representation(self, instance):
        res = super().to_representation(instance)
        if not res.get('description'):
            res['description'] = instance.content[:70]  # 不必传所有的内容
        return res
